package cn.ljy.authority.service;

import cn.ljy.authority.model.dto.SysUserAuthority;

/**
 * 专门用于处理用户的token
 * 规则：
 * 1.上线规则
 * 20221113以前的规则：同一时间只能有一个用户登录，新用户的登录后会踢掉原来的账户。
 * 20221113以后的规则：根据系统配置决定，是否允许一个用户可以登录多次
 * 部分端的token请求，如移动端的token请调用对应的业务类
 * @author ljy
 * 20221113
 */
public interface SysUserTokenService {

    /**
     * 20240728修改token保存在redis中的方式：由原来的key值用userid设计改为使用token。
     * 生成用户的token并返回，并保存到redis中
     * 说明：
     * 1.如果用户原来已经登录并存在token，则会根据网站配置（是否允许用户一次登录多个）来决定是覆盖（即踢掉原来的账户），还是刷新该token的有效期。
     * （1）如果是覆盖或是原来没有token
     * a.通过jwt生成token（有效期为永久）
     * b.将token存储到redis中
     * （2）如果是已经有token存在
     * 返回redis中已经存在的token，并刷新token时间
     * @param userAuthority 对象必须要是从系统中读取
     * @return 返回token
     */
    String saveUserToken(SysUserAuthority userAuthority);

    /**
     * 检查token是否合法。
     * 说明：如果密码已经在其他客户端被修改，也会验证不通过。
     */
    void verifyUserToken(String token);


    /**
     * 检查token是否过期，如果过期抛出异常；如果不过期则刷新该token在redis的时间
     * @param token
     */
    void verifyAndRefreshUserToken(String token);

    /**
     * 从redis中移除用户对应的所有token（备用需求）
     * 说明：
     * 1.设计规则：根据用户的id在redis中找到用户token并删除。
     * @param userAuthority
     */
    void removeUserToken(SysUserAuthority userAuthority);

    /**
     * 从redis中移除token
     * 说明：
     * 1.首先从token中解密获取到对应的userId
     * 2.根据用户的id在redis中找到用户token并删除。
     * 3.补充：如果前端有多个，注销只影响一个端，那么需要设计redis中一个用户根据不同端拥有多个key
     * @param token
     */
    void removeUserToken(String token);

    /**
     * 从token中读取账户名
     * 说明：用于配合其他方法使用
     * @param token
     * @return
     */
    String getUsername(String token);
}
